package com.gaswell.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gaswell.aop.annotation.JHPermission;
import com.gaswell.common.log.LogAnnotation;
import com.gaswell.entity.Qba01;
import com.gaswell.mapper.Qba01Mapper;
import com.gaswell.service.*;
import com.gaswell.utils.DateUtils;
import com.gaswell.vo.Qba01Vo;
import com.gaswell.vo.Result;
import com.gaswell.vo.TestVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * <p>
 * 采气井日数据 前端控制器
 * </p>
 *
 * @author Lei Wang
 * @since 2022-05-24
 */
@RestController
@RequestMapping("/qba01")
@Api(tags = "采气井日数据 前端控制器")
public class Qba01Controller {
    @Autowired
    private IQba01Service iQba01Service;
    @Autowired
    private UserService userService;
    @Autowired
    private Qba01Mapper qba01Mapper;
    @Autowired
    private QjService qjService;

    @Autowired
    private ALLQjService allQjService;

    @Autowired
    private IQba01Service2 qba012Service;

    @Autowired
    private BeanFactory beanFactory;


    @PostMapping("/test")
    @ApiOperation(value = "ceshi")
    public Result selectAll() {
        Qba01Mapper bean = beanFactory.getBean(Qba01Mapper.class);
        List<TestVo> test = qba01Mapper.test();
        return Result.success("");
    }


    @PostMapping("addOne")
    @ApiOperation(value = "添加一条数据")
    @LogAnnotation(module = "采气井日数据", operator = "添加一条数据")
    public Result insertOne(String userName, @RequestBody Qba01 qba01) {
        return iQba01Service.insertOne(qba01);
    }


    @PostMapping("updataOne")
    @ApiOperation(value = "修改一条数据")
    @LogAnnotation(module = "采气井日数据", operator = "修改一条数据")
    public Result updateOne(String userName, @RequestBody Qba01 qba01) {
        return iQba01Service.updateOne(qba01);
    }

    @PostMapping("selectByProperties")
    @ApiOperation(value = "按条件查询（分页）")
    @LogAnnotation(module = "采气井日数据", operator = "按条件查询")
    public Result selectList(String userName, @RequestBody Qba01 qba01, int sort, String start, String end) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        Result result = iQba01Service.selectProperties(qba01, sort, department, start, end);
        return result;
    }

    @PostMapping("selectByMutiProperties")
    @ApiOperation(value = "按条件查询(多选)")
    @LogAnnotation(module = "采气井日数据", operator = "按条件查询（多选）")
    public Result selectData(String userName, @RequestBody Qba01Vo qba01Vo, String date, int sort) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        Result result = iQba01Service.selectByMutiProperties(qba01Vo, date, sort, department);
        return result;
    }


    @PostMapping("selectDuringTime")
    @ApiOperation(value = "按时间段查询")
    @LogAnnotation(module = "采气井日数据", operator = "按时间段查询")
    public Result selectDuringTime() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        List<Qba01> list = iQba01Service.list();
        return Result.success(list.size());
    }


    @PostMapping("selectDuringTimeMultiThread")
    @ApiOperation(value = "按时间段查询  多线程")
    @LogAnnotation(module = "采气井日数据", operator = "按时间段查询  多线程")
    @JHPermission
    public Result selectDuringTimeMultiThread(@RequestParam(required = false) List<String> ywbhs, @RequestParam(required = false) List<String> zwbhs) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        iQba01Service.selectDuringTimeMultiThread(ywbhs, zwbhs);
        return Result.success("");
    }

    @PostMapping("pageByMutiProperties")
    @ApiOperation(value = "按条件分页查询(多选)")
    @LogAnnotation(module = "采气井日数据", operator = "按条件分页查询(多选)")
    public Result pageByMutiProperties(String userName, @RequestBody Qba01Vo qba01Vo, String date, int sort, int current, int size) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        Result result = iQba01Service.pageByMutiProperties(qba01Vo, date, sort, department, current, size);
        return result;
    }

    @PostMapping("selectAll")
    @ApiOperation(value = "查询所有数据（分页）")
    @LogAnnotation(module = "采气井日数据", operator = "查询所有数据")
    public Result selectAll(String userName, int current, int size, String jh, int sort) {
        return iQba01Service.selectAll(current, size, jh, sort);
    }

    @PostMapping("findQm")
    @ApiOperation(value = "查询所有区名")
    @LogAnnotation(module = "采气井日数据", operator = "查询所有区名")
    public Result findQm(String userName) {
        return iQba01Service.findQm();
    }

    @PostMapping("findZm")
    @ApiOperation(value = "查询所有站名")
    @LogAnnotation(module = "采气井日数据", operator = "查询所有站名")
    public Result findZm(String userName) {
        return iQba01Service.findZm();
    }

    @PostMapping("findDm")
    @ApiOperation(value = "查询所有队名")
    @LogAnnotation(module = "采气井日数据", operator = "查询所有队名")
    public Result findDm(String userName) {
        return iQba01Service.findQm();
    }

    @PostMapping("findZyq")
    @ApiOperation(value = "查询所有作业区")
    @LogAnnotation(module = "采气井日数据", operator = "查询所有作业区")
    public Result findZyq(String userName) {
        return iQba01Service.findZyq();
    }

    @PostMapping("findQkmc")
    @ApiOperation(value = "查询所有区块名称")
    @LogAnnotation(module = "采气井日数据", operator = "查询所有区块名称")
    public Result selectAll(String userName) {
        return iQba01Service.findQkmc();
    }


    @GetMapping("/add_all_data")
    public Result add_all_data() {
        List<Qba01> list = iQba01Service.list();
        return Result.success(list);
    }



    @GetMapping("outExcelMultiThread")
    @ApiOperation(value = "导出为excel 多线程")
    @LogAnnotation(module = "采气井日数据", operator = "导出为excel 多线程")
    @JHPermission
    public void outExcelMultiThread(HttpServletResponse response, @RequestParam(required = false) String startDate,
                                    @RequestParam(required = false) String endDate, @RequestParam(required = false) List<String> ywbhs,
                                    @RequestParam(required = false) List<String> zwbhs) throws IOException {
//        zwbhs = allQjService.findZwjh("大庆");
//        ywbhs = allQjService.findYwjh("大庆");
        List<String> finalYwbhs = ywbhs;
        List<String> finalZwbhs = zwbhs;


        long start = System.currentTimeMillis();

        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("采气井日数据", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + fileName + ".xlsx");
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), Qba01.class).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("sheet").build();

        LambdaQueryWrapper<Qba01> qba01LambdaQueryWrapper = new LambdaQueryWrapper<>();
        qba01LambdaQueryWrapper.orderByDesc(Qba01::getRq);
        qba01LambdaQueryWrapper.and(q -> {
            q.in(Qba01::getJh, finalYwbhs).or().in(Qba01::getJh, finalZwbhs);
        });

        if (StringUtils.isNotBlank(startDate))
            qba01LambdaQueryWrapper.ge(Qba01::getRq, DateUtils.stringTosqldate(startDate));
        if (StringUtils.isNotBlank(endDate))
            qba01LambdaQueryWrapper.ge(Qba01::getRq, DateUtils.stringTosqldate(endDate));


        int count = iQba01Service.count(qba01LambdaQueryWrapper);
        System.out.println(count);
        int size = 1000;
        int times = count / size;
        System.out.println(times);


//      存储每个线程取出的数据
        LinkedList<Future<List>> records = new LinkedList<>();

        for (int i = 0; i <= times; i++) {
            System.out.println(i);
            Future<List> booleanFuture = qba012Service.pageForMultiThreadForExcel(qba01LambdaQueryWrapper, i, size);
            records.add(booleanFuture);
        }

        while (!records.isEmpty()) {
            Future<List> pop = records.pop();
//          如果为空继续循环，直到不为空就开始写入excel
            while (!pop.isDone()) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            try {
                excelWriter.write(pop.get(), writeSheet);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }

        long end = System.currentTimeMillis();

        System.out.println((end - start) / 1000);

        excelWriter.finish();
        response.getOutputStream().flush();


    }


    @GetMapping("testOOM")
    public Result testOOM(){
        final List<Qba01> list = iQba01Service.list();
        return Result.success("");
    }

}
